﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SpaceGame
{
    class SpaceGame
    {
        const int WorldRows = 40;
        const int WorldCols = 100;

        static void Main()
        {
            IRenderer renderer = new ConsoleRenderer(WorldRows, WorldCols);
            IInputDevice keyboard = new Keyboard();
            Console.WindowHeight = WorldRows;
            Console.WindowWidth = WorldCols;
            Console.BufferHeight = WorldRows;
            Console.BufferWidth = WorldCols;

            Engine gameEngine = new Engine(renderer, keyboard, 100);

            int choice = 0;
            string input = "";
            DrawGameMenu();
            while (!int.TryParse(input, out choice) || choice < 0 || choice > 2)
            {
                Console.SetCursorPosition(Console.WindowWidth / 2, Console.CursorTop);
                input = Console.ReadLine();
                Console.Clear();
                DrawGameMenu();
            }

            Initialize(gameEngine, choice);
            gameEngine.Run();
        }
        static void DrawGameMenu()
        {
            MenuText("Space Game 1337 Reloaded");
            Console.WriteLine();
            MenuText("To choose wraith ship press 1 and enter");
            Console.WriteLine();
            MenuText("To choose battlecruiser ship press 2 and enter");
        }
        static void MenuText(String text)
        {
            Console.Write(new string(' ', (Console.WindowWidth - text.Length) / 2));
            Console.WriteLine(text);
        }
        static void Initialize(Engine engine, int choice)
        {
            //MovingObject fast = new MovingObject(
            //    new Position(10,10), new char[,]{{'*'}}, 2, new Position(0,1));
            //Destoyer slow = new Destoyer(
            //    new Position(20, 20), new char[,] { { '*' } }, 1, new Position(0, -1));

            //Fighter d = new Fighter(
            //    new Position(20, 10), new char[,] { { '=' },
            //                                        { '|' },
            //                                        { '|' },
            //                                        { '|' },
            //                                        { '=' }});
            if (choice == 1)
            {
                Wraith d = (Wraith)SpaceShipFactory.CreateSpaceShip("wraith",
                   new Position(20, 10));
                engine.AddPlayerSpaceShip(d);
            }
            else if (choice == 2)
            {
                Battlecruiser d = (Battlecruiser)SpaceShipFactory.CreateSpaceShip(
                 "battlecruiser", new Position(30, 30));
                engine.AddPlayerSpaceShip(d);

                //throws the custom exception
                //Battlecruiser d = (Battlecruiser)SpaceShipFactory.CreateSpaceShip(
                // "invalidspaceshiptype", new Position(30, 30));
                //engine.AddPlayerSpaceShip(d);
            }



            //animation
            //d.AddFrame(new char[,] { { '*' } });
            //d.AddFrame(new char[,] { { '.' } });

            PlayerSpaceShip.MaxX = WorldCols;
            PlayerSpaceShip.MaxY = WorldRows;

            for (int i = 0; i < WorldCols; i++)
            {
                SideWallBlock wall = new SideWallBlock(new Position(5, i));
                engine.AddObject(wall);
            }
            for (int i = 0; i < WorldCols; i++)
            {
                SideWallBlock wall = new SideWallBlock(new Position(WorldRows - 1, i));
                engine.AddObject(wall);
            }


            //engine.AddObject(fast);
            //engine.AddObject(slow);

            engine.inputDevice.UpPressed += (sender, evArgs) =>
            {
                engine.PlayerSpaceShip.MoveUp();
            };
            engine.inputDevice.DownPressed += (sender, evArgs) =>
            {
                engine.PlayerSpaceShip.MoveDown();
            };
            engine.inputDevice.RightPressed += (sender, evArgs) =>
            {
                engine.PlayerSpaceShip.MoveRight();
            };
            engine.inputDevice.LeftPressed += (sender, evArgs) =>
            {
                engine.PlayerSpaceShip.MoveLeft();
            };

            engine.inputDevice.ActionPressed += (sender, evArgs) =>
            {
                engine.PlayerSpaceShip.Shoot();
            };

            engine.GameOver += (sender, evArgs) =>
            {
                Console.Clear();
                Console.SetCursorPosition(0, 0);
                Console.WriteLine("END");
                Console.WriteLine("You managed to survive {0} seconds", engine.TotalTime);
            };

            //create some motherfuckers
            int numberOfEnemies = 1;
            int stallPeriod = 10;
            Random random = new Random();
            engine.ProduceEnemies = new ProduceObjectsDelegate(() =>
            {
                if (--stallPeriod == 0)
                {
                    stallPeriod = 10;
                    for (int i = 0; i < numberOfEnemies; i++)
                    {
                        //engine.AddObject(new Destoyer(new Position(random.Next(10, 39), random.Next(WorldCols - 10, WorldCols - 1)),
                        //    new char[,] { { '<', ')' } }, 1, new Position(0, -1)));

                        double enemyKind = random.NextDouble(); // ?? better name
                        Position pos = new Position(random.Next(10, 39), random.Next(WorldCols - 10, WorldCols - 1));
                        if (enemyKind <= 0.5)
                        {
                            Guardian g = (Guardian)SpaceShipFactory.CreateSpaceShip("guardian", pos);
                            engine.AddObject(g);
                        }
                        else
                        {
                            Scourge s = (Scourge)SpaceShipFactory.CreateSpaceShip("scourge", pos);
                            engine.AddObject(s);
                        }

                    }
                }
            });
        }
    }
}
